/*
** Sample object passed to RenderOneFrame
**
** If your game objects have these fields, use them instead.
** Or, put a member variable in here which holds one of your objects.
**
** Revision: %Id$
*/
#include <vector>
using namespace std;


//static const float cfAngularVelocity = 0.5f;


/******************************************************************************\
*                                Object class                                  *
\******************************************************************************/
class Object
{
public:
	/*****************************************************\
	* Structure to hold material and texture information  *
	\*****************************************************/
	typedef struct
	{
		D3DMATERIAL9*		m_pMaterial;	// pointer to material for this subset
		IDirect3DTexture9*	m_pTexture;	// pointer to texture for this subset
	} MESHMATERIAL;
	/* Array of MESHMATERIALs */
	typedef vector<MESHMATERIAL*> MESHMATERIALS;


	/*****************************************************\
	* Member variables                                    *
	\*****************************************************/
	D3DXVECTOR3			m_vPosition;			// location in world coordinates
	D3DXMATRIX			m_mPosition;			// location in world coordinates (this is what RenderOneFrame will look at
	D3DXMATRIX			m_mRotation;			// rotation matrix RenderOneFrame will look at
	D3DXMATRIX			m_mRevolution;			// revolution matrix RenderOneFrame will look at
	D3DXMATRIX			m_mScale;
	float				m_fScale;
	float				m_fRotateAngle;			// for rotation
	float				m_fRevolveAngle;		// for revolving
	float				m_fAngularVelocity;		// speed and direction that the object spins
	float				m_fRevolvingVelocity;	// speed and direction that that object revolves
	DWORD				m_dwSubset;				// index of subset of vertex buffer
	ID3DXMesh*			m_pMesh;				// optimized polygon mesh
	IDirect3DTexture9*	m_pTexture;				// texture for this mesh
	MESHMATERIALS		m_vMaterials;			// materials and textures for each subset
	bool				m_bSpinning;



	/*****************************************************\
	* Object constructor                                  *
	\*****************************************************/
	Object()
	  : m_fRotateAngle(0)
	  , m_fRevolveAngle(0)
	  , m_dwSubset(0)
	  , m_pMesh(NULL)
	  , m_pTexture(NULL)
	  , m_bSpinning(true)
	{
		m_fAngularVelocity = 1.0f;
		m_fRevolvingVelocity = 1.0f;
		m_vPosition = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
		m_vMaterials.clear();
	}


	/*****************************************************\
	* Update example                                      *
	\*****************************************************/
	virtual bool Update(const double dDeltaT)
	{
		//sets up the translation matrix DirectX will look at
		D3DXMatrixTranslation(&m_mPosition,
							  m_vPosition.x, m_vPosition.y, m_vPosition.z);

		//modifies translation matrix based on whether or not it's spinning about its axis
		if (m_bSpinning)
		{
			/* For updating this object, just rotate a little more */
			m_fRotateAngle += (float)(m_fAngularVelocity * dDeltaT);

			D3DXMatrixRotationY(&m_mRotation, m_fRotateAngle);				//creates a rotation matrix based on the spin of the object
			D3DXMatrixMultiply(&m_mPosition, &m_mRotation, &m_mPosition);	//position matrix = rotation angle * old position 
		}

		//further modifies translation matrix to account for the object revolving

		//updates the revolution angle
		m_fRevolveAngle += (float)(m_fRevolvingVelocity * dDeltaT);		//updates revolution angle
		D3DXMatrixRotationY(&m_mRevolution, m_fRevolveAngle);			//creates a rotation matrix based on new angle
		D3DXMatrixMultiply(&m_mPosition, &m_mPosition, &m_mRevolution);	//position matrix = old position * revolution angle

		D3DXMatrixMultiply(&m_mPosition, &m_mScale, &m_mPosition);

		return true;
	}


	/*****************************************************\
	* AddMaterial: put [material,texture] in list         *
	\*****************************************************/
	void AddMaterial(D3DMATERIAL9* pMaterial, IDirect3DTexture9* pTexture)
	{
		MESHMATERIAL meshMaterial;
		meshMaterial.m_pMaterial = pMaterial;
		meshMaterial.m_pTexture = pTexture;
		m_vMaterials.push_back(&meshMaterial);
	}


	/*****************************************************\
	* GetMaterial: get [material,texture] from list       *
	\*****************************************************/
	void GetMaterial(unsigned int n, D3DMATERIAL9** ppMaterial, IDirect3DTexture9** ppTexture)
	{
		MESHMATERIAL* pM = m_vMaterials[n];
		if (NULL != ppMaterial)
		{
			*ppMaterial = pM->m_pMaterial;
		}
		if (NULL != ppTexture)
		{
			*ppTexture = pM->m_pTexture;
		}
	}

	void SetSpinning(bool bSpin) { m_bSpinning = bSpin; }
};


/*****************************************************\
* List of objects                                     *
\*****************************************************/
typedef vector<Object*> ObjectList;
